﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace Zgq.CommonTools
{
    public partial class LambdaToSqlExpression<T>
    {
        public LambdaToSqlExpression() { }

        #region 重置条件
        public LambdaToSqlExpression<T> ResetWhere()
        {
            this.whereExpressionList.Clear();
            return this;
        }
        public LambdaToSqlExpression<T> ResetOrderBy()
        {
            this.orderbyExpressionList.Clear();
            return this;
        }
        public LambdaToSqlExpression<T> ResetSelect()
        {
            this.selectExpressionList.Clear();
            return this;
        }
        public LambdaToSqlExpression<T> ResetAll()
        {
            this.ResetWhere();
            this.ResetOrderBy();
            this.ResetSelect();
            return this;
        }
        #endregion

        #region Where条件
        List<Expression<Func<T, bool>>> whereExpressionList = new List<Expression<Func<T, bool>>>();
        //List<Expression> expressionList = new List<Expression>();
        public LambdaToSqlExpression<T> Where(Expression<Func<T, bool>> _whereExp)
        {
            whereExpressionList.Add(_whereExp);

            return this;
        }
        public string GetWhereStr()
        {
            StringBuilder whereSqlStr = new StringBuilder();

            foreach (var item in whereExpressionList)
            {
                //whereSqlStr.Clear();

                //Console.WriteLine("参数：");
                Expression paramExpression = item.Parameters[0];
                //foreach (var item1 in item.Parameters)
                //{
                //    Start(item1, ref whereSqlStr);
                //}
                if (whereSqlStr.Length > 0) whereSqlStr.CusAppend(" AND ");

                whereSqlStr.Append(Start(item.Body, paramExpression).ToString());
            }
            return whereSqlStr.ToString();
        }
        #endregion

        #region Order By
        Dictionary<Expression<Func<T, object>>, EOrderByType> orderbyExpressionList = new Dictionary<Expression<Func<T, object>>, EOrderByType>();
        public LambdaToSqlExpression<T> OrderBy(Expression<Func<T, object>> _orderbyExp, EOrderByType type = EOrderByType.Asc)
        {
            orderbyExpressionList.Add(_orderbyExp, type);

            return this;
        }

        public string GetOrderByStr()
        {
            StringBuilder orderbySqlStr = new StringBuilder();

            foreach (var item in orderbyExpressionList)
            {
                //orderbySqlStr.Clear();
                //Console.WriteLine("参数：");
                Expression paramExpression = item.Key.Parameters[0];
                //foreach (var item1 in item.Parameters)
                //{
                //    Start(item1, ref whereSqlStr);
                //}
                if (orderbySqlStr.Length > 0) orderbySqlStr.CusAppend(",");

                orderbySqlStr.Append(Start(item.Key.Body, paramExpression).ToString());
                //orderbySqlStr.Replace("][", "],[").Append($" {item.Value}");
                orderbySqlStr.Append($" {item.Value}");
            }

            return orderbySqlStr.ToString();
        }
        #endregion

        #region select 字段
        List<Expression<Func<T, object>>> selectExpressionList = new List<Expression<Func<T, object>>>();
        public LambdaToSqlExpression<T> Select(Expression<Func<T, object>> _selectExp)
        {
            selectExpressionList.Add(_selectExp);

            return this;
        }

        public string GetSelectStr()
        {
            StringBuilder selectColsStr = new StringBuilder();

            foreach (var item in selectExpressionList)
            {
                if (selectColsStr.Length > 0) selectColsStr.CusAppend(",");

                Expression paramExpression = item.Parameters[0];
                selectColsStr.Append(Start(item.Body, paramExpression).ToString());
            }
            return selectColsStr.ToString();
        }
        #endregion

        #region 根据集合筛选
        public List<T> FilterList(List<T> tList)
        {
            if (whereExpressionList.Count == 0) return tList;

            var _where = whereExpressionList[0];

            var f = Expression.Lambda(_where).Compile() as Func<Func<T, bool>>;
            var fTemp = f();
            List<T> tempList = new List<T>();
            foreach (var item in tList)
            {
                if ((bool)fTemp.DynamicInvoke(item))
                    tempList.Add(item);
            }

            return tempList;
        }
        #endregion

        private object Start(Expression expression, Expression paramExpression)
        {
            if (expression is LambdaExpression)
            {
                throw new Exception("LambdaExpression");
                //return new LambdaExpressionResolve(parameter);
            }
            else if (expression is BinaryExpression && expression.NodeType == ExpressionType.Coalesce)
            {
                throw new Exception("expression is BinaryExpression && expression.NodeType == ExpressionType.Coalesce");
                //return new CoalesceResolveItems(parameter);
            }
            else if (expression is BinaryExpression)
            {
                StringBuilder sqlStr = new StringBuilder();
                var binaryExpression = expression as BinaryExpression;
                var tempLeftExp = binaryExpression.Left;
                var noteType = binaryExpression.NodeType;
                sqlStr.CusAppend(" (");
                sqlStr.CusAppend(Start(tempLeftExp, paramExpression).ToString());
                sqlStr.CusAppend($" {GetOperator(noteType)} ");

                var tempExp = binaryExpression.Right;
                sqlStr.CusAppend(Start(tempExp, paramExpression).ToString());

                sqlStr.CusAppend(") ");

                return sqlStr.ToString();
                //return new BinaryExpressionResolve(parameter);
            }
            else if (expression is BlockExpression)
            {
                throw new Exception("BlockExpression");
                //Check.ThrowNotSupportedException("BlockExpression");
            }
            else if (expression is ConditionalExpression)
            {
                throw new Exception("ConditionalExpression");
                //return new ConditionalExpressionResolve(parameter);
            }
            else if (expression is MethodCallExpression)
            {
                MethodCallExpression callExp = expression as MethodCallExpression;
                var v = callExp.Arguments;
                var v1 = callExp.Object;
                var methodName = callExp.Method.Name;
                if (v1 is MemberExpression)
                {
                    MemberExpression memberExpr = v1 as MemberExpression;
                    if (memberExpr.Expression == paramExpression)
                    {
                        var oVal = Start(callExp.Arguments[0], paramExpression);// (callExp.Arguments[0] as ConstantExpression).Value;

                        switch (methodName)
                        {
                            case "Contains":
                                oVal = oVal.ToString().Trim('\'');
                                return $" [{memberExpr.Member.Name}] like '%{oVal}%'";
                            //break;
                            case "StartsWith":
                                oVal = oVal.ToString().Trim('\'');
                                return $" [{memberExpr.Member.Name}] like '{oVal}%'";
                            //break;
                            case "EndsWith":
                                oVal = oVal.ToString().Trim('\'');
                                return $" [{memberExpr.Member.Name}] like '%{oVal}'";
                            //break;
                            case "Equals":
                                return $" [{memberExpr.Member.Name}] = {oVal}";
                        }
                    }
                    else
                    {
                        if (methodName == "Contains")
                        {
                            var memberExprTemp = v[0] as MemberExpression;
                            if (memberExprTemp.Expression == paramExpression)
                            {
                                var oVal = Start(memberExpr, paramExpression);

                                return $" [{memberExprTemp.Member.Name}] in ({ObjJoin(oVal)}) ";
                            }
                        }
                    }
                    return expression.DynamicInvoke();

                }
                else if (v1 == null)
                {
                    MethodCallExpression cv1CallExp = expression as MethodCallExpression;
                    var v1Arg = cv1CallExp.Arguments;
                    var v1Obj = cv1CallExp.Object;
                    var v1MethodName = cv1CallExp.Method.Name;
                    if (v1Arg.Count == 2)
                    {
                        MemberExpression memberExpr = v1Arg[1] as MemberExpression;
                        //sqlStr.CusAppend(string.Format("[{0}]", memberExpr.Member.Name));

                        if (memberExpr.Expression == paramExpression)
                        {
                            var oVal = Start((expression as MethodCallExpression).Arguments[0], paramExpression);// Expression.Lambda((expression as MethodCallExpression).Arguments[0]).Compile().DynamicInvoke(); ;
                            switch (methodName)
                            {
                                case "Contains":
                                    return $" [{memberExpr.Member.Name}] in ({ObjJoin(oVal)}) ";
                                //break;
                                case "Equals":
                                    return $" [{memberExpr.Member.Name}] = {oVal} ";
                                    //break;
                            }
                        }
                        else
                            return Start(memberExpr, paramExpression);
                    }
                    else
                        return expression.DynamicInvoke();
                }
                else
                    return Start(v1, paramExpression);
                //return new MethodCallExpressionResolve(parameter);
            }
            //else if (expression is MemberExpression && ((MemberExpression)expression)
            else if (expression is MemberExpression)
            {
                MemberExpression memberExpr = expression as MemberExpression;
                #region Expression为空
                if (memberExpr.Expression == null)
                {
                    object objReference = null;
                    if (memberExpr.Member is System.Reflection.FieldInfo)
                    {
                        FieldInfo field = (FieldInfo)memberExpr.Member;
                        var reval = field.GetValue(memberExpr.Member);
                        //return new MemberNoExpressionResolve(parameter);
                        var fieldName = memberExpr.Member.Name;
                        var proInfo = reval.GetType().GetProperty(fieldName);
                        if (proInfo != null)
                        {
                            reval = proInfo.GetValue(reval, null);
                        }
                        var fieInfo = reval.GetType().GetField(fieldName);
                        if (fieInfo != null)
                        {
                            reval = fieInfo.GetValue(reval);
                        }
                        objReference = reval;
                    }
                    else if (memberExpr.Member is System.Reflection.PropertyInfo)
                    {
                        PropertyInfo field = (PropertyInfo)memberExpr.Member;
                        var reval = field.GetValue(memberExpr.Member, null);
                        //return new MemberNoExpressionResolve(parameter);
                        var fieldName = memberExpr.Member.Name;
                        var proInfo = reval.GetType().GetProperty(fieldName);
                        if (proInfo != null)
                        {
                            reval = proInfo.GetValue(reval, null);
                        }
                        var fieInfo = reval.GetType().GetField(fieldName);
                        if (fieInfo != null)
                        {
                            reval = fieInfo.GetValue(reval);
                        }
                        objReference = reval;
                    }

                    ExtendClass.ValConvertObj(ref objReference);

                    return objReference;
                }
                #endregion
                #region 常量
                else if (memberExpr.Expression.NodeType == ExpressionType.Constant)
                {
                    var mi = memberExpr.Member;

                    var constExpr = memberExpr.Expression as ConstantExpression;
                    object objReference = null;
                    if (constExpr != null)
                    {
                        objReference = constExpr.Value;

                        if (mi.MemberType == MemberTypes.Property)
                        {
                            var objProp = objReference.GetType().GetProperty(mi.Name);
                            if (objProp == null)
                            {
                                objReference = expression.DynamicInvoke();
                                //objReference = DynamicInvoke(expression);
                            }
                            else
                            {
                                objReference = objProp.GetValue(objReference, null);
                            }
                        }
                        else if (mi.MemberType == MemberTypes.Field)
                        {
                            var objField = objReference.GetType().GetField(mi.Name);
                            if (objField == null)
                            {
                                objReference = expression.DynamicInvoke();
                                //objReference = DynamicInvoke(expression, rootExpression == null ? memberExpr : rootExpression);
                            }
                            else
                            {
                                objReference = objField.GetValue(objReference);
                            }
                        }
                    }
                    ExtendClass.ValConvertObj(ref objReference);
                    return objReference;
                    //return new MemberConstExpressionResolve(parameter);
                }
                #endregion
                else if (memberExpr.Expression.NodeType == ExpressionType.New)
                {
                    throw new Exception("expression is MemberExpression && ((MemberExpression)expression).Expression.NodeType == ExpressionType.New");

                    //return new MemberNewExpressionResolve(parameter);
                }
                else
                {
                    if (memberExpr.Expression == paramExpression)
                        return ($"[{memberExpr.Member.Name}]");
                    else
                        return expression.DynamicInvoke();
                    //return new MemberExpressionResolve(parameter);
                }
            }
            else if (expression is ConstantExpression)
            {
                var constantExpression = expression as ConstantExpression;

                var oVal = constantExpression.Value;

                ExtendClass.ValConvertObj(ref oVal);

                return oVal;
                //return new ConstantExpressionResolve(parameter);
            }
            else if (expression is UnaryExpression)
            {
                UnaryExpression unaryExpr = expression as UnaryExpression;

                if (expression.NodeType == ExpressionType.Convert && expression.Type == typeof(object))
                {
                    MemberExpression memberExpr = unaryExpr.Operand as MemberExpression;
                    if (memberExpr.Expression == paramExpression)
                        return ($"[{memberExpr.Member.Name}]");
                    else
                        return Start(memberExpr.Expression, paramExpression);
                }
                else
                    return expression.DynamicInvoke();

                //return new UnaryExpressionResolve(parameter);
            }
            else if (expression is MemberInitExpression)
            {
                throw new Exception("MemberInitExpression");
                //return new MemberInitExpressionResolve(parameter);
            }
            else if (expression is NewExpression)
            {
                NewExpression newExp = expression as NewExpression;
                StringBuilder strBuilder = new StringBuilder();

                int i = 0;
                foreach (var item in newExp.Arguments)
                {
                    strBuilder.Append(",");
                    var sName = Start(item, paramExpression);
                    string sAliasName = $"[{newExp.Members[i].Name}]";

                    if (sAliasName.Equals(sName))
                        strBuilder.Append(sName);
                    else
                        strBuilder.Append($"{sName} AS {sAliasName}");
                    i++;
                }
                return strBuilder.Remove(0, 1).ToString();
                //return new NewExpressionResolve(parameter);
            }
            else if (expression is NewArrayExpression)
            {
                throw new Exception("NewArrayExpression");
                //return new NewArrayExpessionResolve(parameter);
            }
            else if (expression is ParameterExpression)
            {
                var paramterExp = expression as ParameterExpression;

                var paramName = paramterExp.Name;
                return paramName;
                //return new TypeParameterExpressionReolve(parameter);
            }
            //else if (expression != null && expression.NodeType.IsIn(ExpressionType.NewArrayBounds))
            //{
            //    Check.ThrowNotSupportedException("ExpressionType.NewArrayBounds");
            //}
            return null;
        }

        /*
        private void Start1(Expression expression, Expression paramExpression, ref StringBuilder sqlStr)
        {
            object resultObj = null;
            if (expression is LambdaExpression)
            {
                throw new Exception("LambdaExpression");
                //return new LambdaExpressionResolve(parameter);
            }
            else if (expression is BinaryExpression && expression.NodeType == ExpressionType.Coalesce)
            {
                throw new Exception("expression is BinaryExpression && expression.NodeType == ExpressionType.Coalesce");
                //return new CoalesceResolveItems(parameter);
            }
            else if (expression is BinaryExpression)
            {
                var binaryExpression = expression as BinaryExpression;
                var tempLeftExp = binaryExpression.Left;
                var noteType = binaryExpression.NodeType;
                sqlStr.CusAppend(" (");
                Start(tempLeftExp, paramExpression, ref sqlStr);
                sqlStr.CusAppend($" {GetOperator(noteType)} ");

                var tempExp = binaryExpression.Right;
                Start(tempExp, paramExpression, ref sqlStr);

                sqlStr.CusAppend(") ");
                //return new BinaryExpressionResolve(parameter);
            }
            else if (expression is BlockExpression)
            {
                throw new Exception("BlockExpression");
                //Check.ThrowNotSupportedException("BlockExpression");
            }
            else if (expression is ConditionalExpression)
            {
                throw new Exception("ConditionalExpression");
                //return new ConditionalExpressionResolve(parameter);
            }
            else if (expression is MethodCallExpression)
            {
                MethodCallExpression callExp = expression as MethodCallExpression;
                var v = callExp.Arguments;
                var v1 = callExp.Object;
                var methodName = callExp.Method.Name;
                if (v1 is MemberExpression)
                {
                    MemberExpression memberExpr = v1 as MemberExpression;
                    if (memberExpr.Expression == paramExpression)
                    {
                        sqlStr.CusAppend(string.Format("[{0}]", memberExpr.Member.Name));


                        var oVal = (callExp.Arguments[0] as ConstantExpression).Value;
                        switch (methodName)
                        {
                            case "Contains":
                                sqlStr.CusAppend($" like '%{oVal}%'");
                                break;
                            case "StartsWith":
                                sqlStr.CusAppend($" like '{oVal}%'");
                                break;
                            case "EndsWith":
                                sqlStr.CusAppend($" like '%{oVal}'");
                                break;
                        }
                    }
                    else
                        sqlStr.CusAppendVal(Expression.Lambda(expression).Compile().DynamicInvoke());
                    //sqlStr.CusAppend(reval.ToString());
                }
                else if (v1 == null)
                {
                    MethodCallExpression cv1CallExp = expression as MethodCallExpression;
                    var v1Arg = cv1CallExp.Arguments;
                    var v1Obj = cv1CallExp.Object;
                    var v1MethodName = cv1CallExp.Method.Name;
                    if (v1Arg.Count == 2)
                    {
                        MemberExpression memberExpr = v1Arg[1] as MemberExpression;
                        sqlStr.CusAppend(string.Format("[{0}]", memberExpr.Member.Name));

                        if (memberExpr.Expression == paramExpression)
                        {
                            var oVal = Expression.Lambda((expression as MethodCallExpression).Arguments[0]).Compile().DynamicInvoke(); ;
                            switch (methodName)
                            {
                                case "Contains":
                                    var v111 = oVal as IEnumerable<object>;
                                    sqlStr.CusAppend($" in ({ObjJoin(oVal)}) ");
                                    break;
                                    //case "StartsWith":
                                    //    sqlStr.CusAppend($" like '{oVal}%'");
                                    //    break;
                                    //case "EndsWith":
                                    //    sqlStr.CusAppend($" like '%{oVal}'");
                                    //    break;
                            }


                        }
                        else
                            sqlStr.CusAppendVal(Expression.Lambda(expression).Compile().DynamicInvoke());
                    }
                    else
                        sqlStr.CusAppendVal(Expression.Lambda(expression).Compile().DynamicInvoke());
                }
                //return new MethodCallExpressionResolve(parameter);
            }
            else if (expression is MemberExpression && ((MemberExpression)expression).Expression == null)
            {
                MemberExpression memberExpr = expression as MemberExpression;

                if (memberExpr.Member is System.Reflection.FieldInfo)
                {
                    FieldInfo field = (FieldInfo)memberExpr.Member;
                    var reval = field.GetValue(memberExpr.Member);
                    //return new MemberNoExpressionResolve(parameter);
                    var fieldName = memberExpr.Member.Name;
                    var proInfo = reval.GetType().GetProperty(fieldName);
                    if (proInfo != null)
                    {
                        reval = proInfo.GetValue(reval, null);
                    }
                    var fieInfo = reval.GetType().GetField(fieldName);
                    if (fieInfo != null)
                    {
                        reval = fieInfo.GetValue(reval);
                    }
                    sqlStr.CusAppendVal(reval);
                }
                else if (memberExpr.Member is System.Reflection.PropertyInfo)
                {
                    PropertyInfo field = (PropertyInfo)memberExpr.Member;
                    var reval = field.GetValue(memberExpr.Member);
                    //return new MemberNoExpressionResolve(parameter);
                    var fieldName = memberExpr.Member.Name;
                    var proInfo = reval.GetType().GetProperty(fieldName);
                    if (proInfo != null)
                    {
                        reval = proInfo.GetValue(reval, null);
                    }
                    var fieInfo = reval.GetType().GetField(fieldName);
                    if (fieInfo != null)
                    {
                        reval = fieInfo.GetValue(reval);
                    }
                    sqlStr.CusAppendVal(reval);
                }

            }
            else if (expression is MemberExpression && ((MemberExpression)expression).Expression.NodeType == ExpressionType.Constant)
            {
                var memberExpr = expression as MemberExpression;
                var mi = memberExpr.Member;

                var constExpr = memberExpr.Expression as ConstantExpression;
                object objReference = null;
                if (constExpr != null)
                {


                    objReference = constExpr.Value;

                    if (mi.MemberType == MemberTypes.Property)
                    {
                        var objProp = objReference.GetType().GetProperty(mi.Name);
                        if (objProp == null)
                        {
                            //objReference = DynamicInvoke(expression);
                        }
                        else
                        {
                            objReference = objProp.GetValue(objReference, null);
                        }
                    }
                    else if (mi.MemberType == MemberTypes.Field)
                    {
                        var objField = objReference.GetType().GetField(mi.Name);
                        if (objField == null)
                        {
                            //objReference = DynamicInvoke(expression, rootExpression == null ? memberExpr : rootExpression);
                        }
                        else
                        {
                            objReference = objField.GetValue(objReference);
                        }
                    }
                }
                sqlStr.CusAppendVal(objReference);
                //return new MemberConstExpressionResolve(parameter);
            }
            else if (expression is MemberExpression && ((MemberExpression)expression).Expression.NodeType == ExpressionType.New)
            {
                throw new Exception("expression is MemberExpression && ((MemberExpression)expression).Expression.NodeType == ExpressionType.New");

                //return new MemberNewExpressionResolve(parameter);
            }
            else if (expression is ConstantExpression)
            {
                var constantExpression = expression as ConstantExpression;

                var oVal = constantExpression.Value;
                sqlStr.CusAppendVal(oVal);
                //return new ConstantExpressionResolve(parameter);
            }
            else if (expression is MemberExpression)
            {
                MemberExpression memberExpr = expression as MemberExpression;
                if (memberExpr.Expression == paramExpression)
                    sqlStr.CusAppend($"[{memberExpr.Member.Name}]");
                else
                    sqlStr.CusAppendVal(Expression.Lambda(expression).Compile().DynamicInvoke());

                //return new MemberExpressionResolve(parameter);
            }
            else if (expression is UnaryExpression)
            {
                UnaryExpression unaryExpr = expression as UnaryExpression;

                if (expression.NodeType == ExpressionType.Convert && expression.Type == typeof(object))
                {
                    MemberExpression memberExpr = unaryExpr.Operand as MemberExpression;
                    if (memberExpr.Expression == paramExpression)
                        sqlStr.CusAppendVal($"[{memberExpr.Member.Name}]");
                    else
                        sqlStr.CusAppendVal(Expression.Lambda(expression).Compile().DynamicInvoke());
                }
                else
                    sqlStr.CusAppendVal(Expression.Lambda(expression).Compile().DynamicInvoke());

                //return new UnaryExpressionResolve(parameter);
            }
            else if (expression is MemberInitExpression)
            {
                throw new Exception("MemberInitExpression");
                //return new MemberInitExpressionResolve(parameter);
            }
            else if (expression is NewExpression)
            {
                NewExpression newExp = expression as NewExpression;
                foreach (var item in newExp.Arguments)
                {
                    Start(item, paramExpression, ref sqlStr);
                }
                //return new NewExpressionResolve(parameter);
            }
            else if (expression is NewArrayExpression)
            {
                throw new Exception("NewArrayExpression");
                //return new NewArrayExpessionResolve(parameter);
            }
            else if (expression is ParameterExpression)
            {
                var paramterExp = expression as ParameterExpression;

                var paramName = paramterExp.Name;
                sqlStr.CusAppend(paramName.ToString());
                //return new TypeParameterExpressionReolve(parameter);
            }
            //else if (expression != null && expression.NodeType.IsIn(ExpressionType.NewArrayBounds))
            //{
            //    Check.ThrowNotSupportedException("ExpressionType.NewArrayBounds");
            //}
            //return null;
        }
        */
        string ObjJoin(object obj)
        {

            string result = null;
            var objType = obj.GetType().Name;
            switch (objType)
            {
                case "Int32[]":
                    {
                        var vArray = obj as Int32[];
                        result = string.Join(",", vArray);
                    }
                    break;
                case "Decimal[]":
                    {
                        var vArray = obj as Decimal[];
                        result = string.Join(",", vArray);
                    }
                    break;
                case "Double[]":
                    {
                        var vArray = obj as Double[];
                        result = string.Join(",", vArray);
                    }
                    break;
                case "String[]":
                    {
                        var vArray = obj as String[];
                        result = string.Join(",", vArray.Select(s => $"'{s}'"));
                    }
                    break;
                case "DateTime[]":
                    {
                        var vArray = obj as DateTime[];
                        result = string.Join(",", vArray.Select(s => $"'{s}'"));
                    }
                    break;
                default:
                    {
                        if (obj is IEnumerable<int>)
                        {
                            var vArray = obj as IEnumerable<int>;
                            result = string.Join(",", vArray);
                        }
                        else if (obj is IEnumerable<Decimal>)
                        {
                            var vArray = obj as IEnumerable<Decimal>;
                            result = string.Join(",", vArray);
                        }
                        else if (obj is IEnumerable<Double>)
                        {
                            var vArray = obj as IEnumerable<Double>;
                            result = string.Join(",", vArray);
                        }
                        else if (obj is IEnumerable<String>)
                        {
                            var vArray = obj as IEnumerable<String>;
                            result = string.Join(",", vArray.Select(s => $"'{s}'"));
                        }
                        else if (obj is IEnumerable<DateTime>)
                        {
                            var vArray = obj as IEnumerable<DateTime>;
                            result = string.Join(",", vArray.Select(s => $"'{s}'"));
                        }
                    }
                    break;

            }

            return result;
        }

        public static string GetOperator(ExpressionType expressiontype)
        {
            switch (expressiontype)
            {
                case ExpressionType.And:
                case ExpressionType.AndAlso:
                    return "AND";
                case ExpressionType.Equal:
                    return "=";
                case ExpressionType.GreaterThan:
                    return ">";
                case ExpressionType.GreaterThanOrEqual:
                    return ">=";
                case ExpressionType.LessThan:
                    return "<";
                case ExpressionType.LessThanOrEqual:
                    return "<=";
                case ExpressionType.NotEqual:
                    return "<>";
                case ExpressionType.Or:
                case ExpressionType.OrElse:
                    return "OR";
                case ExpressionType.Add:
                case ExpressionType.AddChecked:
                    return "+";
                case ExpressionType.Subtract:
                case ExpressionType.SubtractChecked:
                    return "-";
                case ExpressionType.Divide:
                    return "/";
                case ExpressionType.Multiply:
                case ExpressionType.MultiplyChecked:
                    return "*";
                case ExpressionType.Modulo:
                    return "%";
                case ExpressionType.Coalesce:
                    throw new Exception("Expression no support ?? ,Use SqlFunc.IsNull");
                default:
                    //Check.ThrowNotSupportedException(string.Format(ErrorMessage.OperatorError, expressiontype.ToString()));
                    return null;
            }
        }
    }

}
